package cn.turboinfo.fuyang.api.domain.common.component.common;

import cn.turboinfo.fuyang.api.entity.common.enumeration.common.EntityObjectType;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@RequiredArgsConstructor
@Component
public class EntityObjectHelper {

    /**
     * 批量获取并反写对象类型和ID实际代表的对象可读名称表述
     *
     * @param collection         要反写的原始对象集合
     * @param objectTypeMapper   从原始对象中获取到对象类型和ID的方法
     * @param objectNameConsumer 反写的方法
     * @param <T>                原始对象类型
     */
    public <T> void resolveFriendlyEntityObjectName(Collection<T> collection,
                                                    Function<T, Pair<EntityObjectType, Long>> objectTypeMapper,
                                                    BiConsumer<T, String> objectNameConsumer) {
        // 先进行对象分组以便批量查询
        Map<T, Pair<EntityObjectType, Long>> collectionMap = new HashMap<>();
        collection.forEach(it -> collectionMap.put(it, objectTypeMapper.apply(it)));
        Map<EntityObjectType, Set<Long>> objectTypeGroupMap = collectionMap.values()
                .stream()
                .collect(
                        Collectors.groupingBy(Pair::getLeft, Collectors.mapping(Pair::getRight, Collectors.toSet()))
                );

        Map<EntityObjectType, Map<Long, String>> objectTypeGroupNameMap = new HashMap<>();
        for (EntityObjectType objectType : objectTypeGroupMap.keySet()) {
            switch (objectType) {
                default:
                    break;
            }
        }
        // 回写
        for (Map.Entry<T, Pair<EntityObjectType, Long>> entry : collectionMap.entrySet()) {
            T original = entry.getKey();
            Pair<EntityObjectType, Long> pair = entry.getValue();
            if (objectTypeGroupNameMap.containsKey(pair.getKey())) {
                Map<Long, String> nameMap = objectTypeGroupNameMap.get(pair.getKey());
                if (nameMap.containsKey(pair.getRight())) {
                    objectNameConsumer.accept(original, nameMap.get(pair.getRight()));
                }
            }
        }
    }
}
